package com.mpolicy.dbfile.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

@Slf4j
public class FileUtils {

    /**
     * 获取文件内容
     * @return
     */
    public static String getFileContent(String path) {
        StringBuilder result = new StringBuilder();
        try {
            // 读取文件内容到Stream流中，按行读取
            Stream<String> lines = Files.lines(Paths.get(path));
            // 随机行顺序进行数据处理
            lines.forEach(result::append);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    /**
     * 获取文件内容
     * @return
     */
    public static String getFileContent(InputStream is) {
        StringBuilder result = new StringBuilder();
        try {
            byte[] bytes = new byte[is.available()];
            is.read(bytes);
            result.append(new String(bytes));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(is);
        }
        return result.toString();
    }

    /**
     * 获取文章内容
     * @param file
     * @return
     */
    public static String getFileContent(File file) {
        String result = null;
        try {
            result = getFileContent(new FileInputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static File createFile(String filePath) throws IOException {
        File file = new File(filePath);
        if(file.exists()) {
            return file;
        }
        if(!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        file.createNewFile();
        return file;
    }

    /**
     * 获取文件名称
     *
     * @param file
     * @return
     */
    public static String getFileName(MultipartFile file) {
        return file.getOriginalFilename();
    }

    /**
     * 获取文件后缀
     *
     * @param file
     * @return
     */
    public static String getFileSuffix(MultipartFile file) {
        String fileName = getFileName(file);
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }


    /**
     * 获取不带后缀的文件名
     *
     * @param file
     * @return
     */
    public static String getFileNameWithoutSuffix(MultipartFile file) {
        String fileName = getFileName(file);
        return fileName.substring(0, fileName.lastIndexOf("."));
    }

    /**
     * 获取文件大小
     *
     * @param file
     * @return
     */
    public static int getFileSize(MultipartFile file) {
        return (int)file.getSize();
    }

    /**
     * 获取文件二进制流
     * @param inputStream
     * @return
     */
    public static byte[] toByte(InputStream inputStream, boolean needClose) throws IOException {
        BufferedInputStream bis = null;
        ByteArrayOutputStream bos = null;
        try {
            bis = new BufferedInputStream(inputStream);
            bos = new ByteArrayOutputStream();
            int len = 0;
            byte[] b = new byte[2048];
            while((len=bis.read(b))>-1) {
                bos.write(b, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            throw e;
        } finally {
            IOUtils.closeQuietly(bis);
            IOUtils.closeQuietly(bos);
            if(needClose && inputStream!=null) {
                IOUtils.closeQuietly(inputStream);
            }
        }
    }

    /**
     * 下载
     *
     * @param urlAddress url
     */
    public static void download(String urlAddress, OutputStream outputStream) throws Exception {
        URLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            URL url = new URL(urlAddress);
            urlConnection = url.openConnection();
            inputStream = urlConnection.getInputStream();

            byte[] buf = new byte[2048];
            int byteRead;
            while ((byteRead = inputStream.read(buf)) != -1) {
                outputStream.write(buf, 0, byteRead);
                outputStream.flush();
            }
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    public static void deleteFile(File file) {
        if(file!=null && file.exists()) {
            file.delete();
        }
    }

    /**
     * 输出流输出文件
     * @param file
     * @param response
     */
    public static void writeFile(File file, String name, HttpServletResponse response) throws IOException {
        ServletUtils.registerFileStreamResponseHeader(name, response);
        FileUtils.writeFile(new FileInputStream(file), response.getOutputStream());
    }

    /**
     * 输出流输出文件
     * @param inputStream
     * @param outputStream
     */
    public static void writeFile(InputStream inputStream, OutputStream outputStream) throws IOException {
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try {
            bos = new BufferedOutputStream(outputStream);
            bis = new BufferedInputStream(inputStream);
            byte[] bytes = new byte[2048];
            int num = 0;
            while ((num=bis.read(bytes))!=-1) {
                bos.write(bytes, 0, num);
            }
            outputStream.flush();
        } finally {
            IOUtils.closeQuietly(bos);
            IOUtils.closeQuietly(bis);
        }
    }

    /**
     * 输出流输出文件
     * @param inputStream
     * @param file
     */
    public static void writeFile(InputStream inputStream, File file) throws IOException {
        writeFile(inputStream, new FileOutputStream(file));
    }

    /**
     * 二进制流输出文件
     * @param bytes
     */
    public static void writeFile(byte[] bytes, File file) throws IOException {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } finally {
            IOUtils.closeQuietly(bos);
            IOUtils.closeQuietly(fos);
        }
    }

    /**
     * 二进制流输出到输出流
     * @param bytes
     */
    public static void writeFile(byte[] bytes, OutputStream outputStream) throws IOException {
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(outputStream);
            bos.write(bytes);
            bos.flush();
        } finally {
            IOUtils.closeQuietly(bos);
            IOUtils.closeQuietly(outputStream);
        }
    }

    /**
     * 二进制流输出到输出流
     * @param bytes
     */
    public static void writeFile(byte[] bytes, String fileName, HttpServletResponse response) throws IOException {
        ServletUtils.registerFileStreamResponseHeader(fileName, response);
        writeFile(bytes, response.getOutputStream());
    }

    /**
     * 获取根路径
     * @return
     */
    public static String getRootPath() {
        String root = System.getProperty("user.dir");
        if (root.startsWith("/")) {
            root = "/usr/local/docker/update";
        }
        return root;
    }

    public static byte[] getFileBytes(File tempExcel) {
        try {
            return toByte(new FileInputStream(tempExcel), true);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("读取文件二进制流异常");
        }
    }
}
